require 'spec_helper'

module Bosh::Director
  module Models
    describe Vm do
      include IpUtil
      subject(:vm) { FactoryBot.create(:models_vm, instance: instance) }

      let!(:instance) { FactoryBot.create(:models_instance) }

      it 'has a many-to-one relationship to instances' do
        FactoryBot.create(:models_vm, instance_id: instance.id, id: 1)
        FactoryBot.create(:models_vm, instance_id: instance.id, id: 2)

        expect(Vm.find(id: 1).instance).to eq(instance)
        expect(Vm.find(id: 2).instance).to eq(instance)
      end

      describe '#network_spec' do
        it 'unmarshals network_spec_json' do
          vm.network_spec_json = JSON.dump('some' => 'spec')

          expect(vm.network_spec).to eq('some' => 'spec')
        end

        context 'when network_spec_json is nil' do
          it 'returns empty hash' do
            vm.network_spec_json = nil

            expect(vm.network_spec).to eq({})
          end
        end
      end

      describe '#network_spec=' do
        it 'sets network_spec_json with json-ified value' do
          vm.network_spec = { 'some' => 'spec' }

          expect(vm.network_spec_json).to eq(JSON.dump('some' => 'spec'))
        end
      end

      describe '#ips' do
        let!(:ip_address) { FactoryBot.create(:models_ip_address, vm: vm, address_str: to_ipaddr('1.1.1.1/32').to_s) }
        let!(:ip_address2) { FactoryBot.create(:models_ip_address, vm: vm, address_str: to_ipaddr('1.1.1.2/32').to_s) }
        let!(:ip_address3) { FactoryBot.create(:models_ip_address, vm: vm, address_str: to_ipaddr('1.1.1.16/28').to_s) }

        before do
          vm.network_spec = { 'some' => { 'ip' => '2001:db8::1', 'prefix' => '64' }, 'some_other' => { 'ip' => '1.1.1.4', 'prefix' => '32' } }
        end

        it 'returns ips without prefix for single ips and with prefix for prefix ips order by size of the integer representation' do
          expect(vm.ips).to match_array(['1.1.1.1', '1.1.1.2', '1.1.1.16/28', '1.1.1.4', '2001:db8::1/64'])
        end

        context 'with old VMs that do not have a prefix' do
          before do
            vm.network_spec = { 'some' => { 'ip' => '2001:db8::1' }, 'some_other' => { 'ip' => '1.1.1.4' } }
          end

          it 'returns ips without prefix for single ips and with prefix for prefix ips order by size of the integer representation' do
            expect(vm.ips).to match_array(['1.1.1.1', '1.1.1.2', '1.1.1.16/28', '1.1.1.4', '2001:db8::1'])
          end
        end
      end
    end
  end
end
